package com.lineage.server.timecontroller.pc;

import com.lineage.config.ConfigOther;
import com.lineage.server.datatables.MapHprMprRangeTable;
import com.lineage.server.datatables.MapHprMprTable;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.L1HouseLocation;
import com.lineage.server.types.Point;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class MprExecutor {
  private static final Log _log = LogFactory.getLog(MprExecutor.class);
  
  private static final Map<Integer, Integer> _skill = new HashMap<>();
  
  private static final Map<Integer, Integer> _mapId = new HashMap<>();
  
  private static MprExecutor _instance;
  
  private MprExecutor() {
    _skill.put(Integer.valueOf(32), Integer.valueOf(5));
    _skill.put(Integer.valueOf(206), Integer.valueOf(2));
    _skill.put(Integer.valueOf(3002), Integer.valueOf(3));
    _skill.put(Integer.valueOf(3010), Integer.valueOf(3));
    _skill.put(Integer.valueOf(3020), Integer.valueOf(2));
    _skill.put(Integer.valueOf(3028), Integer.valueOf(2));
    _skill.put(Integer.valueOf(3037), Integer.valueOf(2));
    _skill.put(Integer.valueOf(3045), Integer.valueOf(2));
  }
  
  protected static MprExecutor get() {
    if (_instance == null)
      _instance = new MprExecutor(); 
    return _instance;
  }
  
  private static void regenMp(L1PcInstance tgpc) {
    tgpc.set_mpRegenType(0);
    if (tgpc.getMapId() == 201)
      return; 
    int baseMpr = 1;
    switch (tgpc.getWis()) {
      case 0:
      case 1:
      case 2:
      case 3:
      case 4:
      case 5:
      case 6:
      case 7:
      case 8:
      case 9:
      case 10:
      case 11:
      case 12:
      case 13:
      case 14:
        baseMpr = 1;
        break;
      case 15:
      case 16:
        baseMpr = 2;
        break;
      default:
        baseMpr = 3;
        break;
    } 
    if (!tgpc.getSkillisEmpty() && tgpc.getSkillEffect().size() > 0)
      try {
        Iterator<Integer> iterator = tgpc.getSkillEffect().iterator();
        while (iterator.hasNext()) {
          Integer key = iterator.next();
          if (key.equals(Integer.valueOf(32))) {
            if (tgpc.getHpRegenState() != 4) {
              tgpc.killSkillEffectTimer(32);
              continue;
            } 
            int sec = tgpc.getSkillEffectTimeSec(32);
            if (!tgpc.hasSkillEffect(1002)) {
              baseMpr += 5;
            } else {
              baseMpr += 5 + 2 * Math.min((640 - sec) / 32, 8);
            } 
          } 
          if (key.equals(Integer.valueOf(1002))) {
            baseMpr += Math.max(tgpc.getWis() - 10, 1);
            continue;
          } 
          Integer integer = _skill.get(key);
          if (integer == null)
            continue; 
          baseMpr += integer.intValue();
        } 
      } catch (ConcurrentModificationException concurrentModificationException) {
      
      } catch (Exception e) {
        _log.error(e.getLocalizedMessage(), e);
      }  
    short mapid = tgpc.getMapId();
    int mapmp = MapHprMprTable.get().getMapMpr(mapid);
    int maphp1 = MapHprMprTable.get().getMapMpr(32767);
    int maphp3 = MapHprMprRangeTable.get().getMapMpr(tgpc, mapid);
    if (mapmp != 0)
      baseMpr += mapmp; 
    if (maphp3 != 0)
      baseMpr += maphp3; 
    if (L1HouseLocation.isInHouse(tgpc.getX(), tgpc.getY(), tgpc.getMapId()))
      baseMpr += maphp1; 
    Integer rmp = _mapId.get(Short.valueOf(tgpc.getMapId()));
    if (rmp != null)
      baseMpr += rmp.intValue(); 
    if (tgpc.isElf() && tgpc.getMapId() == 4 && tgpc.getLocation().isInScreen(new Point(33055, 32336)))
      baseMpr += ConfigOther.FORESTMPR; 
    if (tgpc.getOriginalMpr() > 0)
      baseMpr += tgpc.getOriginalMpr(); 
    int itemMpr = tgpc.getInventory().mpRegenPerTick();
    itemMpr += tgpc.getMpr();
    int mpr = baseMpr + itemMpr;
    int newMp = tgpc.getCurrentMp() + mpr;
    newMp = Math.max(newMp, 0);
    tgpc.setCurrentMp(newMp);
  }
  
  protected boolean check(L1PcInstance tgpc) {
    try {
      if (tgpc == null)
        return false; 
      if (tgpc.getOnlineStatus() == 0)
        return false; 
      if (tgpc.getNetConnection() == null)
        return false; 
      if (tgpc.isDead())
        return false; 
      if (tgpc.isTeleport())
        return false; 
      if (tgpc.getCurrentMp() >= tgpc.getMaxMp())
        return false; 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
      return false;
    } 
    return true;
  }
  
  protected void checkRegenMp(L1PcInstance tgpc) {
    try {
      tgpc.set_mpRegenType(tgpc.mpRegenType() + tgpc.getMpRegenState());
      tgpc.setRegenState(8);
      if (tgpc.isRegenMp())
        regenMp(tgpc); 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
}
